// 我喜欢的对象页面：展示用户“喜欢的对象（模板）”列表，支持懒加载与移除喜欢
// - 进入页面后：POST /api/template/getMyLikedTemplatesRoute，携带 page、page_size、language（拦截器自动注入 language）
// - 点击卡片：弹出详情（封装子组件），展示大图与统计，并可移除喜欢或创建图片
// - 移除喜欢：POST /api/template/unlikeTemplateRoute，成功后从列表移除
// - UI：Tailwind；支持 PC/移动端与暗黑模式

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useI18n } from "@/utils/in18";
import { useNavigate } from "react-router-dom";
import { request } from "@/utils/request";
import { getStoredBearerToken, hasStoredToken } from "@/utils/auth";
import LikedTemplateModal, { LikedTemplateItem } from "./components/LikedTemplateModal";

// 接口返回数据结构
type ListResponse = {
  success: boolean;
  data: LikedTemplateItem[];
  total: number;
  page: number;
  page_size: number;
};

// 分页页大小常量（可按需调整）
const DEFAULT_PAGE_SIZE = 12;

const MyLikedPersionPage: React.FC = () => {
  // 列表与分页状态
  const [items, setItems] = useState<LikedTemplateItem[]>([]);
  const [page, setPage] = useState<number>(1);
  const [pageSize, setPageSize] = useState<number>(DEFAULT_PAGE_SIZE);
  const [total, setTotal] = useState<number>(0);
  const [loading, setLoading] = useState<boolean>(false);

  // 多选管理相关
  const [editMode, setEditMode] = useState<boolean>(false);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [bulkConfirmOpen, setBulkConfirmOpen] = useState<boolean>(false);
  const [bulkConfirmLoading, setBulkConfirmLoading] = useState<boolean>(false);
  const [bulkLanguage, setBulkLanguage] = useState<string>('');

  // 详情弹窗状态
  const [detailOpen, setDetailOpen] = useState<boolean>(false);
  const [current, setCurrent] = useState<LikedTemplateItem | null>(null);
  // 卡片层面的二次确认状态（点击心形弹窗）
  const [confirmOpenCard, setConfirmOpenCard] = useState<boolean>(false);
  const [confirmTargetId, setConfirmTargetId] = useState<number | null>(null);
  const [confirmLoadingCard, setConfirmLoadingCard] = useState<boolean>(false);

  const navigate = useNavigate();
  const { t } = useI18n();
  const goBack = useCallback(() => {
    try {
      if (window.history.length > 1) {
        navigate(-1);
      } else {
        navigate("/");
      }
    } catch {
      navigate("/");
    }
  }, [navigate]);

  const toggleSelect = (id: number) => {
    setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));
  };

  // 加载喜欢的模板列表（初始或刷新 - 替换数据）
  const fetchList = useCallback(async (p = page, ps = pageSize) => {
    if (!hasStoredToken()) return;
    setLoading(true);
    try {
      const authHeader = getStoredBearerToken();
      if (!authHeader) return;
      const resp = await request.post<ListResponse>("/api/template/getMyLikedTemplatesRoute", { page: p, page_size: ps }, { headers: { Authorization: authHeader } });
      const list = resp?.data?.data || [];
      setItems(list);
      setTotal(resp?.data?.total || 0);
      setPage(resp?.data?.page || p);
      setPageSize(resp?.data?.page_size || ps);
    } catch (e) {
      // 错误提示已在拦截器处理
    } finally {
      setLoading(false);
    }
  }, [page, pageSize]);

  // 懒加载（IntersectionObserver）
  const loadingMoreRef = useRef(false);
  const observerRef = useRef<IntersectionObserver | null>(null);
  const sentinelRef = useRef<HTMLDivElement | null>(null);

  const fetchMore = useCallback(async () => {
    if (loading || loadingMoreRef.current) return;
    if (!hasStoredToken()) return;
    const totalPages = Math.max(1, Math.ceil(total / pageSize));
    const nextPage = Math.min(Math.max(1, page + 1), totalPages);
    if (page >= totalPages) return;

    loadingMoreRef.current = true;
    try {
      const authHeader = getStoredBearerToken();
      if (!authHeader) return;
      const resp = await request.post<ListResponse>("/api/template/getMyLikedTemplatesRoute", { page: nextPage, page_size: pageSize }, { headers: { Authorization: authHeader } });
      const list = resp?.data?.data || [];
      setItems((prev) => {
        const existingIds = new Set(prev.map((it) => it.id));
        const filtered = list.filter((it) => !existingIds.has(it.id));
        return filtered.length ? [...prev, ...filtered] : prev;
      });
      setTotal(resp?.data?.total ?? total);
      setPage(nextPage);
    } catch (e) {
      // ignore
    } finally {
      loadingMoreRef.current = false;
    }
  }, [loading, page, pageSize, total]);

  useEffect(() => {
    fetchList(1, pageSize);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!sentinelRef.current) return;
    if (observerRef.current) observerRef.current.disconnect();
    observerRef.current = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) fetchMore();
      });
    }, { root: null, rootMargin: '200px', threshold: 0.01 });
    observerRef.current.observe(sentinelRef.current);
    return () => {
      if (observerRef.current) {
        observerRef.current.disconnect();
        observerRef.current = null;
      }
    };
  }, [fetchMore]);

  // 打开详情
  const openDetail = (it: LikedTemplateItem) => {
    setCurrent(it);
    setDetailOpen(true);
  };

  // 二次确认后，调用取消喜欢接口，并从列表移除
  const handleConfirmUnlike = useCallback(async (templateId: number) => {
    try {
      const authHeader = getStoredBearerToken();
      if (!authHeader) return;
      const resp = await request.post<{ success: boolean; is_liked: boolean; removed?: boolean; likes_count?: number }>(
        "/api/template/unlikeTemplateRoute",
        { template_id: templateId },
        { headers: { Authorization: authHeader } }
      );
      if (resp?.data?.success) {
        setItems((prev) => prev.filter((it) => it.id !== templateId));
        setTotal((t) => Math.max(0, t - 1));
        // 若当前详情即该项，则关闭弹窗
        if (current?.id === templateId) {
          setDetailOpen(false);
          setCurrent(null);
        }
      }
    } catch { }
  }, [current]);

  // 批量取消喜欢
  const handleBulkUnlike = useCallback(async () => {
    if (selectedIds.length === 0) return;
    try {
      setBulkConfirmLoading(true);
      const authHeader = getStoredBearerToken();
      if (!authHeader) return;

      // 语言转换：如果传空则服务端视为中文
      const payload: any = { template_id: selectedIds };
      if (bulkLanguage) payload.language = bulkLanguage;

      const resp = await request.post<{ success: boolean; results?: any[] }>(
        '/api/template/unlikeTemplateRoute',
        payload,
        { headers: { Authorization: authHeader } }
      );

      if (resp?.data?.success) {
        // 如果返回 results，则使用 returned template_id 去移除；否则使用 selectedIds
        const removedIds = Array.isArray(resp.data.results)
          ? resp.data.results.filter((r) => r.removed).map((r) => r.template_id)
          : selectedIds;

        setItems((prev) => prev.filter((it) => !removedIds.includes(it.id)));
        setTotal((t) => Math.max(0, t - removedIds.length));
        setSelectedIds([]);
        setBulkConfirmOpen(false);
        setEditMode(false);
        // 关闭详情如果其已被移除
        if (current && removedIds.includes(current.id)) {
          setDetailOpen(false);
          setCurrent(null);
        }
      }
    } catch (e) {
      // ignore
    } finally {
      setBulkConfirmLoading(false);
    }
  }, [selectedIds, bulkLanguage, current]);

  // 跳转到创建图片（隐藏 URL 参数，使用 state）
  const handleCreateImage = useCallback((it: LikedTemplateItem) => {
    try {
      navigate("/CreateImage", {
        state: {
          image_url: it.image_url,
          // 需求：携带 id 与 role_prompt，但不暴露到 URL；后续页面从 location.state 读取
          template_id: it.id,
          role_prompt: it.role_prompt,
          category: (it as any)?.category,
        },
      });
    } catch { }
  }, [navigate]);

  const totalPages = useMemo(() => Math.max(1, Math.ceil(total / pageSize)), [total, pageSize]);

  return (
    <div className="w-full md:w-[70%] mx-auto px-4 md:px-6 md:py-6 min-h-[var(--content-h)] sm:min-h-full">
      {/* 自定义返回标题栏 */}
      <div className="sticky justify-between top-0 z-20 bg-white/80 dark:bg-[#111111]/80 backdrop-blur border-b border-gray-200 dark:border-gray-800 h-14 flex items-center ">
        <button
          onClick={goBack}
          className="rounded flex items-center text-black dark:text-white hover:bg-gray-100 dark:hover:bg-[#1a1a1a]"
          aria-label="Back"
        >
          <svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M15 18l-6-6 6-6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
          {/* 标题  */}
          <div>
            <h2 className="text-base md:text-lg font-semibold text-gray-900 dark:text-gray-100">{t('my_liked_persion.title')}</h2>
          </div>
        </button>


        {/* 管理按钮 */}
        <div className=" flex items-center gap-2">
          {editMode && (
            <button
              onClick={() => setBulkConfirmOpen(true)}
              className="px-3 py-1 rounded bg-red-500 text-white text-sm"
            >
              {t('my_liked_persion.delete_selected')}
            </button>
          )}
          <button
            onClick={() => {
              setEditMode((v) => !v);
              if (editMode) setSelectedIds([]);
            }}
            className="px-3 py-1  dark:bg-gray-100 bg-[#111] dark:text-black text-sm rounded"
          >
            {editMode ? t('my_liked_persion.cancel') : t('my_liked_persion.management')}
          </button>
        </div>
      </div>

      {/* 列表网格 */}
      <div className="mt-4 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3 sm:gap-4">
        {loading && (
          <div className="col-span-full text-center text-sm text-gray-500 dark:text-gray-400">{t('my_liked_persion.loading')}</div>
        )}

        {!loading && items.length === 0 && (
          <div className="col-span-full text-center text-sm text-gray-500 dark:text-gray-400">{t('my_liked_persion.no_data')}</div>
        )}

        {!loading && items.map((it) => (
          <div key={it.id} className="group relative rounded-xl overflow-hidden border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0b0b0b] shadow-sm">
            {/* 复选框（编辑模式） */}
            {editMode && (
              <input
                type="checkbox"
                checked={selectedIds.includes(it.id)}
                onChange={() => toggleSelect(it.id)}
                className="absolute top-2 left-2 z-30 w-5 h-5"
                onClick={(e) => e.stopPropagation()}
              />
            )}
            <button className="block w-full" onClick={() => openDetail(it)}>
              <div className="relative w-full" style={{ paddingTop: '167.1875%' }}>
                <img src={it.image_url} alt={it.name || t('my_liked_persion.image_alt')} className="absolute inset-0 w-full h-full object-cover" />
              </div>
            </button>
            <div className="p-2 sm:p-3 text-xs sm:text-sm flex items-center justify-end">
              <div className="flex items-center gap-2 text-gray-700 dark:text-gray-200">
                {/* 点赞数 */}
                <div className="inline-flex items-center gap-1">
                  <button
                    aria-label={t('my_liked_persion.unlike')}
                    onClick={(e) => {
                      e.stopPropagation();
                      setConfirmTargetId(it.id);
                      setConfirmOpenCard(true);
                    }}
                    className="inline-flex items-center gap-1 px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-[#111]"
                  >
                    <span className={it.is_liked ? "text-red-500" : "text-gray-500"}>
                      <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2507" width="18" height="18" className="text-inherit"><path d="M512 998.4c-19.2 0-38.4-12.8-38.4-19.2C454.4 966.4 128 640 83.2 595.2 32 537.6 0 467.2 0 396.8s32-147.2 83.2-198.4c51.2-51.2 121.6-83.2 198.4-83.2 76.8 0 147.2 32 198.4 83.2C492.8 211.2 505.6 224 512 236.8c6.4-12.8 19.2-25.6 32-38.4 51.2-51.2 121.6-83.2 198.4-83.2 76.8 0 147.2 32 198.4 83.2C992 249.6 1024 320 1024 396.8c0 76.8-32 147.2-83.2 198.4C896 640 569.6 966.4 550.4 979.2 550.4 985.6 531.2 998.4 512 998.4z" fill="currentColor" p-id="2346"></path></svg>
                    </span>
                    <span className="text-gray-700 dark:text-gray-200">{it.likes_count ?? 0}</span>
                  </button>
                </div>
              </div>
            </div>
          </div>
        ))}
        {/* sentinel：用于触发加载更多 */}
        <div ref={sentinelRef as any} className="col-span-full h-2" />
      </div>

      {/* 底部加载指示器（当有更多数据时显示） */}
      {page < totalPages && (
        <div className="mt-4 text-center text-sm text-gray-500 dark:text-gray-400">{t('my_liked_persion.loading_more')}</div>
      )}

      {/* 详情弹窗 */}
      <LikedTemplateModal
        open={detailOpen}
        item={current}
        onClose={() => setDetailOpen(false)}
        onConfirmUnlike={handleConfirmUnlike}
        onCreateImage={handleCreateImage}
      />

      {/* 批量取消喜欢确认弹窗 */}
      {bulkConfirmOpen && (
        <div className="fixed inset-0 z-[12000] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-black/50" onClick={() => bulkConfirmLoading ? null : setBulkConfirmOpen(false)} />
          <div className="relative z-10 w-full max-w-md rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0b0b0b] p-4 shadow-xl">
            <div className="text-base font-semibold text-gray-900 dark:text-gray-100">{t('my_liked_persion.bulk_confirm_title')}</div>
            <div className="mt-2 text-sm text-gray-600 dark:text-gray-300">{t('my_liked_persion.bulk_confirm_message') + ` (${selectedIds.length})`}</div>
            <div className="mt-4 flex justify-end gap-2">
              <button onClick={() => setBulkConfirmOpen(false)} className="px-3 py-1 rounded text-gray-600 dark:text-gray-300 bg-gray-100" disabled={bulkConfirmLoading}>{t('my_liked_persion.cancel')}</button>
              <button onClick={handleBulkUnlike} className="px-3 py-1 rounded bg-red-500 text-white" disabled={bulkConfirmLoading}>{bulkConfirmLoading ? t('my_liked_persion.please_wait') : t('my_liked_persion.confirm')}</button>
            </div>
          </div>
        </div>
      )}

      {/* 卡片层面的移除喜欢二次确认弹窗 */}
      {confirmOpenCard && confirmTargetId !== null && (
        <div className="fixed inset-0 z-[12000] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-black/50" onClick={() => confirmLoadingCard ? null : setConfirmOpenCard(false)} />
          <div className="relative z-10 w-full max-w-sm rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0b0b0b] p-4 shadow-xl">
            <div className="text-base font-semibold text-gray-900 dark:text-gray-100">{t('my_liked_persion.confirm_title')}</div>
            <div className="mt-2 text-sm text-gray-600 dark:text-gray-300">{t('my_liked_persion.confirm_message')}</div>
            <div className="mt-4 flex justify-end gap-2">
              <button
                className="px-3 py-1.5 text-sm text-gray-500 dark:text-gray-400 rounded border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-[#111]"
                onClick={() => setConfirmOpenCard(false)}
                disabled={confirmLoadingCard}
              >
                {t('my_liked_persion.cancel')}
              </button>
              <button
                className="px-3 py-1.5 text-sm rounded bg-red-600 text-white hover:opacity-90"
                onClick={async () => {
                  try {
                    setConfirmLoadingCard(true);
                    await handleConfirmUnlike(confirmTargetId as number);
                    setConfirmOpenCard(false);
                    setConfirmTargetId(null);
                  } finally {
                    setConfirmLoadingCard(false);
                  }
                }}
                disabled={confirmLoadingCard}
              >
                {confirmLoadingCard ? t('my_liked_persion.please_wait') : t('my_liked_persion.confirm')}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default MyLikedPersionPage;


